package com.aqielife.demo.service;

import com.aqielife.demo.entity.City;
import com.aqielife.demo.repository.CityReactiveRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @author aqie
 * @date 2022/02/04 19:56
 * @desc
 */
@Slf4j
@Service("cityServiceMongoImpl")
public class CityServiceImpl implements CityService {

  @Autowired
  private RedisTemplate<String, City> redisTemplate;

  @Autowired
  private CityReactiveRepository cityRepository;

  public Mono<ServerResponse> helloCity(ServerRequest request) {
    return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
    .body(BodyInserters.fromObject("Hello, City!"));
  }

  public Mono<City> findCityById(String id) {
    // 从缓存中获取城市信息
    String key = "city_" + id;
    ValueOperations<String, City> operations = redisTemplate.opsForValue();

    // 缓存存在
    boolean hasKey = redisTemplate.hasKey(key);
    if (hasKey) {
      City city = operations.get(key);

      log.info("CityHandler.findCityById() : 从缓存中获取了城市 >> " + city.toString());
      return Mono.create(cityMonoSink -> cityMonoSink.success(city));
    }

    // 从 MongoDB 中获取城市信息
    Mono<City> cityMono = cityRepository.findById(id);

    // 插入缓存
    cityMono.subscribe(cityObj -> {
      operations.set(key, cityObj);
      log.info("CityHandler.findCityById() : 城市插入缓存 >> " + cityObj.toString());
    }, e -> log.error("set data error:", e));

    return cityMono;
  }

  public Flux<City> findAllCity() {
    return cityRepository.findAll();
  }

  public Mono<City> save(City city) {
    return cityRepository.save(city);
  }

  public Mono<City> modifyCity(City city) {
    // 修改mongodb
    Mono<City> cityMono = cityRepository.save(city);

    // 缓存存在，删除缓存
    String key = "city_" + city.getId();
    boolean hasKey = redisTemplate.hasKey(key);
    if (hasKey) {
      redisTemplate.delete(key);
      log.info("CityHandler.modifyCity() : 从缓存中删除城市 ID >> " + city.getId());
    }
    return cityMono;
  }

  public void deleteCity(String id) {
    cityRepository.deleteById(id);

    // 缓存存在，删除缓存
    String key = "city_" + id;
    boolean hasKey = redisTemplate.hasKey(key);
    if (hasKey) {
      redisTemplate.delete(key);
      log.info("CityHandler.deleteCity() : 从缓存中删除城市 ID >> " + id);
    }
  }
}

